Fix shadow bitmap sizing for logdirty mode.
authorsmh22@firebug.cl.cam.ac.uk <smh22@firebug.cl.cam.ac.uk>
Wed, 9 Nov 2005 18:18:47 +0000 (19:18 +0100)
committersmh22@firebug.cl.cam.ac.uk <smh22@firebug.cl.cam.ac.uk>
Wed, 9 Nov 2005 18:18:47 +0000 (19:18 +0100)
Signed-off-by: Steven Hand <steven@xensource.com>
xen/arch/x86/shadow32.c
xen/arch/x86/shadow_public.c

index 0d68f508279c91044d9d9dfedfeb769723fc266e..6270f8186e1e40a9b49db8425fa3810751a6be15 100644 (file)
@@ -997,7 +997,8 @@ int __shadow_mode_enable(struct domain *d, unsigned int mode)
     if ( new_modes & SHM_log_dirty )
     {
         ASSERT( !d->arch.shadow_dirty_bitmap );
-        d->arch.shadow_dirty_bitmap_size = (d->max_pages + 63) & ~63;
+        d->arch.shadow_dirty_bitmap_size = 
+            (d->shared_info->arch.max_pfn +  63) & ~63;
         d->arch.shadow_dirty_bitmap = 
             xmalloc_array(unsigned long, d->arch.shadow_dirty_bitmap_size /
                                          (8 * sizeof(unsigned long)));
@@ -1287,34 +1288,28 @@ static int shadow_mode_table_op(
         d->arch.shadow_dirty_net_count   = 0;
         d->arch.shadow_dirty_block_count = 0;
  
-        if ( (d->max_pages > sc->pages) || 
-             (sc->dirty_bitmap == NULL) || 
+        if ( (sc->dirty_bitmap == NULL) || 
              (d->arch.shadow_dirty_bitmap == NULL) )
         {
             rc = -EINVAL;
             break;
         }
-        sc->pages = d->max_pages;
+
+        if(sc->pages > d->arch.shadow_dirty_bitmap_size)
+            sc->pages = d->arch.shadow_dirty_bitmap_size; 
 
 #define chunk (8*1024) /* Transfer and clear in 1kB chunks for L1 cache. */
-        for ( i = 0; i < d->max_pages; i += chunk )
+        for ( i = 0; i < sc->pages; i += chunk )
         {
-            int bytes = ((((d->max_pages - i) > chunk) ?
-                          chunk : (d->max_pages - i)) + 7) / 8;
+            int bytes = ((((sc->pages - i) > chunk) ?
+                          chunk : (sc->pages - i)) + 7) / 8;
      
             if (copy_to_user(
                     sc->dirty_bitmap + (i/(8*sizeof(unsigned long))),
                     d->arch.shadow_dirty_bitmap +(i/(8*sizeof(unsigned long))),
                     bytes))
             {
-                // copy_to_user can fail when copying to guest app memory.
-                // app should zero buffer after mallocing, and pin it
                 rc = -EINVAL;
-                memset(
-                    d->arch.shadow_dirty_bitmap + 
-                    (i/(8*sizeof(unsigned long))),
-                    0, (d->max_pages/8) - (i/(8*sizeof(unsigned long))));
                 break;
             }
 
@@ -1331,17 +1326,19 @@ static int shadow_mode_table_op(
         sc->stats.dirty_net_count   = d->arch.shadow_dirty_net_count;
         sc->stats.dirty_block_count = d->arch.shadow_dirty_block_count;
  
-        if ( (d->max_pages > sc->pages) || 
-             (sc->dirty_bitmap == NULL) || 
+
+        if ( (sc->dirty_bitmap == NULL) || 
              (d->arch.shadow_dirty_bitmap == NULL) )
         {
             rc = -EINVAL;
             break;
         }
  
-        sc->pages = d->max_pages;
-        if (copy_to_user(
-            sc->dirty_bitmap, d->arch.shadow_dirty_bitmap, (d->max_pages+7)/8))
+        if(sc->pages > d->arch.shadow_dirty_bitmap_size)
+            sc->pages = d->arch.shadow_dirty_bitmap_size; 
+
+        if (copy_to_user(sc->dirty_bitmap, 
+                         d->arch.shadow_dirty_bitmap, (sc->pages+7)/8))
         {
             rc = -EINVAL;
             break;
index 3cf71242f9b879366b9d136a10f3f1d289a5d46c..39f1ba851e4cc618663ac38473509b1d4ffc6e50 100644 (file)
@@ -1009,7 +1009,8 @@ int __shadow_mode_enable(struct domain *d, unsigned int mode)
     if ( new_modes & SHM_log_dirty )
     {
         ASSERT( !d->arch.shadow_dirty_bitmap );
-        d->arch.shadow_dirty_bitmap_size = (d->max_pages + 63) & ~63;
+        d->arch.shadow_dirty_bitmap_size = 
+            (d->shared_info->arch.max_pfn +  63) & ~63;
         d->arch.shadow_dirty_bitmap = 
             xmalloc_array(unsigned long, d->arch.shadow_dirty_bitmap_size /
                           (8 * sizeof(unsigned long)));
@@ -1163,34 +1164,29 @@ static int shadow_mode_table_op(
         d->arch.shadow_dirty_net_count   = 0;
         d->arch.shadow_dirty_block_count = 0;
  
-        if ( (d->max_pages > sc->pages) || 
-             (sc->dirty_bitmap == NULL) || 
+
+        if ( (sc->dirty_bitmap == NULL) || 
              (d->arch.shadow_dirty_bitmap == NULL) )
         {
             rc = -EINVAL;
             break;
         }
-        sc->pages = d->max_pages;
+
+        if(sc->pages > d->arch.shadow_dirty_bitmap_size)
+            sc->pages = d->arch.shadow_dirty_bitmap_size; 
 
 #define chunk (8*1024) /* Transfer and clear in 1kB chunks for L1 cache. */
-        for ( i = 0; i < d->max_pages; i += chunk )
+        for ( i = 0; i < sc->pages; i += chunk )
         {
-            int bytes = ((((d->max_pages - i) > chunk) ?
-                          chunk : (d->max_pages - i)) + 7) / 8;
+            int bytes = ((((sc->pages - i) > chunk) ?
+                          chunk : (sc->pages - i)) + 7) / 8;
 
             if (copy_to_user(
                 sc->dirty_bitmap + (i/(8*sizeof(unsigned long))),
                 d->arch.shadow_dirty_bitmap +(i/(8*sizeof(unsigned long))),
                 bytes))
             {
-                // copy_to_user can fail when copying to guest app memory.
-                // app should zero buffer after mallocing, and pin it
                 rc = -EINVAL;
-                memset(
-                    d->arch.shadow_dirty_bitmap + 
-                    (i/(8*sizeof(unsigned long))),
-                    0, (d->max_pages/8) - (i/(8*sizeof(unsigned long))));
                 break;
             }
             memset(
@@ -1206,17 +1202,18 @@ static int shadow_mode_table_op(
         sc->stats.dirty_net_count   = d->arch.shadow_dirty_net_count;
         sc->stats.dirty_block_count = d->arch.shadow_dirty_block_count;
  
-        if ( (d->max_pages > sc->pages) || 
-             (sc->dirty_bitmap == NULL) || 
+        if ( (sc->dirty_bitmap == NULL) || 
              (d->arch.shadow_dirty_bitmap == NULL) )
         {
             rc = -EINVAL;
             break;
         }
  
-        sc->pages = d->max_pages;
-        if (copy_to_user(
-            sc->dirty_bitmap, d->arch.shadow_dirty_bitmap, (d->max_pages+7)/8))
+        if(sc->pages > d->arch.shadow_dirty_bitmap_size)
+            sc->pages = d->arch.shadow_dirty_bitmap_size; 
+
+        if (copy_to_user(sc->dirty_bitmap, 
+                         d->arch.shadow_dirty_bitmap, (sc->pages+7)/8))
         {
             rc = -EINVAL;
             break;